package gits

import (
	"errors"
	"fmt"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/object"
	"github.com/go-git/go-git/v5/plumbing/transport/http"
	"github.com/go-git/go-git/v5/storage/memory"
	"os"
	"strings"
	"time"
)

// GOGIT 文档
// https://blog.csdn.net/u014686399/article/details/108334869

var gitUser = "heyevan@163.com"
var gitPassword = "13140215"
var gitAuth = &http.BasicAuth{Username: gitUser, Password: gitPassword}

//var token = "ce40f169e441557f97503fb7d46089bc"
//var gitAuth = &http.TokenAuth{Token: token}

// Clone2Memory clone to memory
func Clone2Memory(url string, branch string) (*git.Repository, error) {
	r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
		URL:           url,
		ReferenceName: plumbing.ReferenceName(branch),
		Auth:          gitAuth,
		Progress:      os.Stdout,
	})
	if err != nil {
		return nil, err
	}
	return r, nil
}

// Clone2Disk clone to disk
func Clone2Disk(directory string, url string, branch string, ignoreExist bool) (*git.Repository, error) {
	r, err := git.PlainClone(directory, true, &git.CloneOptions{
		URL:           url,
		ReferenceName: plumbing.ReferenceName(branch),
		Auth:          gitAuth,
		Progress:      os.Stdout,
	})
	if err != nil {
		if strings.Contains(err.Error(), "repository already exists") {
			return git.PlainOpen(directory)
		} else {
			return nil, err
		}
	}
	return r, nil
}

// Add ansiblePath 是你的目录的名字，注意这里是指在clone后的工程目录里相对路径
func Add(r *git.Repository, relativePathOfRepository string) (plumbing.Hash, error) {
	//获取工程树
	var hash plumbing.Hash
	var tree *git.Worktree
	var treeErr error
	tree, treeErr = r.Worktree()
	if treeErr != nil {
		return hash, errors.New(fmt.Sprintf("GitAddError|%s", treeErr.Error()))
	}

	//拷贝文件过来
	hash, err := tree.Add(relativePathOfRepository)
	if err != nil {
		return hash, errors.New(fmt.Sprintf("GitAddError|%s:%s", relativePathOfRepository, err.Error()))
	}
	return hash, err
}

// Commit git 提交
func Commit(r *git.Repository, message string) (*object.Commit, error) {
	//获取工程树
	var commits *object.Commit
	tree, err := r.Worktree()
	if err != nil {
		return commits, errors.New(fmt.Sprintf("GitCommitError|%s", err.Error()))
	}

	//git commit
	var hash plumbing.Hash
	hash, err = tree.Commit(message, &git.CommitOptions{
		All: true,
		Author: &object.Signature{
			Name:  gitUser,
			Email: gitUser,
			When:  time.Now(),
		},
	})
	commits, err = r.CommitObject(hash)
	if err != nil {
		return commits, errors.New(fmt.Sprintf("GitCommitError|%s", err.Error()))
	}
	return commits, nil
}

// Push git 提交
func Push(r *git.Repository) error {
	/*err := r.Push(&git.PushOptions{
		RemoteName: "origin",
		RefSpecs:   []config.RefSpec{config.RefSpec("+refs/heads/*:refs/remotes/origin/*")},
		Auth:       gitAuth,
	})*/
	err := r.Push(&git.PushOptions{
		Auth: gitAuth,
	})
	if err != nil {
		return errors.New(fmt.Sprintf("GitPushError|%s", err.Error()))
	}
	return nil
}
